package com.heima.cjlib动态代理;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.InvocationHandler;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * 需求：在不修改list.add方法逻辑的基础上增强其功能，要求：每次添加完，自动打印添加的元素内容。
 * 使用动态代理实现!
 * 1. spring aop底层原理是什么？  -- 动态代理
 * 2. 动态代理的实现有哪些？      -- jdk实现和cjlib实现
 * 3. jdk和cjlib实现的区别？
 *      jdk基于proxy实现的动态代理，主要是基于接口来产生代理对象，
 *                              代理对象和原始对象实现了相同接口，是平级的兄弟关系
 *      cjlib基于enhacer实现的动态代理，主要是基于原始对象的类的字节码来产生代理对象，
 *                              代理对象可以理解为是原始对象的子类，是父子关系。
 *
 */
public class Demo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(list.getClass());
        enhancer.setCallback(new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                if ("add".equals(method.getName())) {
                    System.out.println("本次添加的元素是："+objects[0]);
                }
                //反射调用原始对象功能
                Object ret = method.invoke(list, objects);
                return ret;
            }
        });

        ArrayList proxyList = (ArrayList) enhancer.create();
        proxyList.add("hello");
        proxyList.add("world");
        proxyList.add("java");
        System.out.println("list = " + list);
    }
}
